﻿using System;
using System.Collections;
using System.Linq;
using System.Text;

namespace Tibet.Logica
{
    /// <summary>
    /// Clase que implementa el patron de diseño Singleton. Controla las listas de reportes que cada
    /// usuario conectado al sistema puede tener.
    /// </summary>
    public class ReportesControlador
    {
        /// <summary>
        /// Lista del objeto ListaReporte, se generará una entrada en esta lista por cada usuario concurrente
        /// y se identificaran por id.
        /// </summary>
        private ArrayList _Listas;

        public ArrayList Listas
        {
            get { return _Listas; }
            set { _Listas = value; }
        }

        private static ReportesControlador _instacia;

        
        /// <summary>
        /// Constructor
        /// </summary>
        private ReportesControlador()
        {
            this._Listas = new ArrayList();
        }

        /// <summary>
        /// Regresa la instancia del sigleton.
        /// </summary>
        /// <returns></returns>
        public static ReportesControlador Obtener() 
        {
            if (ReportesControlador._instacia == null)
            {
                ReportesControlador._instacia = new ReportesControlador();
            }
            return ReportesControlador._instacia;
        }

        /// <summary>
        /// Regresa la lista de reportes de la pantalla inicial de ese usuario.
        /// </summary>
        /// <param name="idUsuario"></param>
        /// <returns>Lista de reportes</returns>
        public ArrayList obtenerMostrarIni(int idUsuario)
        {

            ArrayList respuesta = new ArrayList();
            try
            {
                //Se busca la lista asiganda a ese usuario.
                foreach (ListaReportes a in Listas)
                {
                    if (a.IdUsuario == idUsuario)
                    {
                        a.destruirMostrados();
                        a.agregarMostrados(FabricaReporte.CrearRepEstaProy());
                        a.agregarMostrados(FabricaReporte.CrearRepDesarrolladores());
                        respuesta = a.ListaMostrados;
                    }
                }

                // Si el usuario no tiene una lista asiganada, se le crea una.
                if (respuesta.Count == 0)
                {
                    ListaReportes Nuevo = new ListaReportes();
                    Nuevo = crearLista(idUsuario);
                    Nuevo.agregarMostrados(FabricaReporte.CrearRepEstaProy());
                    Nuevo.agregarMostrados(FabricaReporte.CrearRepDesarrolladores());
                    respuesta = Nuevo.ListaMostrados;

                }
                return respuesta;
            }
            catch (Exception)
            {          
                return respuesta;
            }
        }

        /// <summary>
        /// Muestra los reportes de todas las metricas del proyecto elegido.
        /// </summary>
        /// <param name="idUsuario">Id del usuario</param>
        /// <param name="idP"> Id del proyecto</param>
        /// <returns></returns>
        public ArrayList obtenerMostrarEst(int idUsuario,int idP)
        {
            ArrayList respuesta = new ArrayList();
            //Se busca la lista asiganda a ese usuario.
            try
            {
                foreach (ListaReportes a in Listas)
                {
                    if (a.IdUsuario == idUsuario)
                    {
                        a.destruirMostrados();
                        a.agregarMostrados(FabricaReporte.CrearReporteTLOC(idP));
                        a.agregarMostrados(FabricaReporte.CrearReporteNSM(idP));
                        a.agregarMostrados(FabricaReporte.CrearReporteNORM(idP));
                        respuesta = a.ListaMostrados;
                    }
                }

                // Si el usuario no tiene una lista asiganada, se le crea una.
                if (respuesta.Count == 0)
                {
                    ListaReportes Nuevo = new ListaReportes();
                    Nuevo = crearLista(idUsuario);
                    Nuevo.agregarMostrados(FabricaReporte.CrearReporteTLOC(idP));
                    Nuevo.agregarMostrados(FabricaReporte.CrearReporteNSM(idP));
                    Nuevo.agregarMostrados(FabricaReporte.CrearReporteNORM(idP));
                    respuesta = Nuevo.ListaMostrados;

                }
                return respuesta;
            }
            catch (Exception e)
            {
                return respuesta;
            }
        }

        /// <summary>
        /// Agrega el reporte a la lista de seleccionados por el usuario, esta lista sirve para agrupar varios reportes
        /// antes de exportarlos.
        /// </summary>
        /// <param name="idUsuario">ID del usuario</param>
        /// <param name="nuevo">Reporte a incluir</param>
        public void agregarLista(int idUsuario, Reporte nuevo)
        {
            foreach (ListaReportes a in Listas)
            {
                if (a.IdUsuario == idUsuario)
                {
                    a.ListaAgregados.Add(nuevo);
                }
            }
        }

        /// <summary>
        /// Regresa la lista de reportes seleccionados de ese usuario.
        /// </summary>
        /// <param name="IdUsuario">ID del usuario</param>
        /// <returns></returns>
        public ArrayList obtenerLista(int IdUsuario)
        {
            ArrayList respuesta = new ArrayList();
            foreach (ListaReportes a in Listas)
            {
                if (a.IdUsuario == IdUsuario)
                {
                    respuesta = a.ListaAgregados;                    
                }
            }
            return respuesta;
        }

        /// <summary>
        /// Se asigana una lista nueva a un usuario, solo se utiliza cuando el usuario aun no tiene una lista
        /// en esta clase.
        /// </summary>
        /// <param name="IdUsuario"></param>
        /// <returns></returns>
        public ListaReportes crearLista(int IdUsuario)
        {
            ListaReportes Nuevo = new ListaReportes();
            Nuevo.IdUsuario = IdUsuario;
            this._Listas.Add(Nuevo);
            return Nuevo;
        }

        /// <summary>
        /// Muestra los reportes de errores.
        /// </summary>
        /// <param name="idUsuario">ID Usuario</param>
        /// <returns></returns>
        public ArrayList obtenerMostrarErr(int idUsuario)
        {
            ArrayList respuesta = new ArrayList();
            //Se busca la lista asiganda a ese usuario.
            foreach (ListaReportes a in Listas)
            {
                if (a.IdUsuario == idUsuario)
                {
                    a.destruirMostrados();
                    a.agregarMostrados(FabricaReporte.CrearRepErrProy());
                    a.agregarMostrados(FabricaReporte.CrearRepErrDesa());
                    respuesta = a.ListaMostrados;
                }
            }

            // Si el usuario no tiene una lista asiganada, se le crea una.
            if (respuesta.Count == 0)
            {
                ListaReportes Nuevo = new ListaReportes();
                Nuevo = crearLista(idUsuario);
                Nuevo.agregarMostrados(FabricaReporte.CrearRepErrProy());
                Nuevo.agregarMostrados(FabricaReporte.CrearRepErrDesa());
                respuesta = Nuevo.ListaMostrados;

            }
            return respuesta;
        }

        /// <summary>
        /// Borra un reporte de la lista de seleccionados de ese usuario.
        /// </summary>
        /// <param name="idUsuario">ID del Usuario</param>
        /// <param name="pos">Posicion del reporte en la lista</param>
        public void borrarDeLista(int idUsuario, int pos)
        {
            foreach (ListaReportes a in Listas)
            {
                if (a.IdUsuario == idUsuario)
                {
                    a.ListaAgregados.RemoveAt(pos);
                }
            }

        }


    }
}
